<template>
  <div class="slam-realtime-view">
    <div class="bg-white rounded-2xl shadow-lg p-6 border border-gray-100">
      <div class="flex items-center justify-between mb-4">
        <h3 class="text-lg font-semibold text-gray-800 flex items-center">
          <i class="fa-solid fa-video mr-2 text-purple-500"></i>
          SLAM实时建模画面
        </h3>
        <div class="flex items-center space-x-2">
          <span :class="getStatusColor(status)" class="px-2 py-1 rounded-full text-xs font-medium">
            {{ getStatusText(status) }}
          </span>
          <button 
            @click="toggleFullscreen" 
            class="px-3 py-1 bg-gray-500 text-white rounded text-xs hover:bg-gray-600 transition-colors"
          >
            <i class="fa-solid fa-expand mr-1"></i>
            全屏
          </button>
        </div>
      </div>
      
      <!-- 视频显示区域 -->
      <div class="relative bg-gray-900 rounded-lg overflow-hidden mb-4" :class="fullscreen ? 'fixed inset-0 z-50' : 'h-96'">
        <!-- 主视频流 -->
        <div class="relative w-full h-full">
          <video 
            ref="mainVideo"
            :src="videoSrc"
            autoplay
            muted
            playsinline
            class="w-full h-full object-cover"
            @loadeddata="onVideoLoaded"
            @error="onVideoError"
          ></video>
          
          <!-- 加载状态 -->
          <div v-if="loading" class="absolute inset-0 flex items-center justify-center bg-black/50">
            <div class="text-center text-white">
              <i class="fa-solid fa-spinner fa-spin text-2xl mb-2"></i>
              <p>正在加载视频流...</p>
            </div>
          </div>
          
          <!-- 无视频状态 -->
          <div v-else-if="!hasVideo" class="absolute inset-0 flex items-center justify-center bg-gray-800">
            <div class="text-center text-white">
              <i class="fa-solid fa-video-slash text-4xl mb-4 text-gray-400"></i>
              <p class="text-lg mb-2">暂无视频流</p>
              <p class="text-sm text-gray-400">请启动SLAM建图会话</p>
            </div>
          </div>
          
          <!-- 视频控制覆盖层 -->
          <div v-if="hasVideo" class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-4">
            <div class="flex items-center justify-between text-white">
              <div class="flex items-center space-x-4">
                <button 
                  @click="togglePlayPause" 
                  class="p-2 bg-white/20 rounded-full hover:bg-white/30 transition-colors"
                >
                  <i :class="isPlaying ? 'fa-pause' : 'fa-play'" class="fa-solid"></i>
                </button>
                <div class="flex items-center space-x-2">
                  <span class="text-sm">{{ formatTime(currentTime) }}</span>
                  <span class="text-sm text-gray-300">/</span>
                  <span class="text-sm">{{ formatTime(duration) }}</span>
                </div>
              </div>
              
              <div class="flex items-center space-x-2">
                <button 
                  @click="toggleMute" 
                  class="p-2 bg-white/20 rounded-full hover:bg-white/30 transition-colors"
                >
                  <i :class="isMuted ? 'fa-volume-mute' : 'fa-volume-up'" class="fa-solid"></i>
                </button>
                <button 
                  @click="toggleFullscreen" 
                  class="p-2 bg-white/20 rounded-full hover:bg-white/30 transition-colors"
                >
                  <i :class="fullscreen ? 'fa-compress' : 'fa-expand'" class="fa-solid"></i>
                </button>
              </div>
            </div>
            
            <!-- 进度条 -->
            <div class="mt-2">
              <div class="w-full bg-white/20 rounded-full h-1">
                <div 
                  class="bg-purple-500 h-1 rounded-full transition-all duration-300"
                  :style="{ width: progressPercentage + '%' }"
                ></div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- SLAM信息覆盖层 -->
        <div v-if="hasVideo && slamInfo" class="absolute top-4 left-4 bg-black/70 rounded-lg p-3 text-white">
          <div class="space-y-1 text-sm">
            <div class="flex items-center space-x-2">
              <i class="fa-solid fa-map text-purple-400"></i>
              <span>关键帧: {{ slamInfo.keyframes || 0 }}</span>
            </div>
            <div class="flex items-center space-x-2">
              <i class="fa-solid fa-circle text-blue-400"></i>
              <span>地图点: {{ slamInfo.mappoints || 0 }}</span>
            </div>
            <div class="flex items-center space-x-2">
              <i class="fa-solid fa-route text-green-400"></i>
              <span>轨迹长度: {{ (slamInfo.trajectoryLength || 0).toFixed(2) }}m</span>
            </div>
          </div>
        </div>
        
        <!-- 退出全屏按钮 -->
        <button 
          v-if="fullscreen" 
          @click="exitFullscreen"
          class="absolute top-4 right-4 p-2 bg-black/70 text-white rounded-full hover:bg-black/80 transition-colors"
        >
          <i class="fa-solid fa-times"></i>
        </button>
      </div>
      
      <!-- 控制面板 -->
      <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
        <div class="bg-gray-50 rounded-lg p-4">
          <div class="flex items-center justify-between">
            <span class="text-sm text-gray-600">视频源</span>
            <span class="text-sm font-semibold text-gray-800">{{ videoSource || '未设置' }}</span>
          </div>
        </div>
        
        <div class="bg-gray-50 rounded-lg p-4">
          <div class="flex items-center justify-between">
            <span class="text-sm text-gray-600">分辨率</span>
            <span class="text-sm font-semibold text-gray-800">{{ videoResolution }}</span>
          </div>
        </div>
        
        <div class="bg-gray-50 rounded-lg p-4">
          <div class="flex items-center justify-between">
            <span class="text-sm text-gray-600">帧率</span>
            <span class="text-sm font-semibold text-gray-800">{{ frameRate }}fps</span>
          </div>
        </div>
      </div>
      
      <!-- 操作按钮 -->
      <div class="flex space-x-2">
        <button 
          @click="startVideoStream" 
          :disabled="!canStart"
          class="flex-1 px-4 py-2 bg-purple-500 text-white rounded-lg hover:bg-purple-600 transition-colors disabled:opacity-50"
        >
          <i class="fa-solid fa-play mr-1"></i>
          开始视频流
        </button>
        
        <button 
          @click="stopVideoStream" 
          :disabled="!canStop"
          class="px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50"
        >
          <i class="fa-solid fa-stop mr-1"></i>
          停止
        </button>
        
        <button 
          @click="refreshVideoStream" 
          class="px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors"
        >
          <i class="fa-solid fa-refresh mr-1"></i>
          刷新
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, computed } from 'vue'
import axios from 'axios'

const props = defineProps({
  sessionId: {
    type: Number,
    required: true
  }
})

// 响应式数据
const mainVideo = ref(null)
const loading = ref(false)
const hasVideo = ref(false)
const status = ref('STOPPED')
const isPlaying = ref(false)
const isMuted = ref(true)
const fullscreen = ref(false)
const currentTime = ref(0)
const duration = ref(0)
const videoSrc = ref('')
const videoSource = ref('')
const videoResolution = ref('未知')
const frameRate = ref(0)
const slamInfo = ref(null)

// 计算属性
const progressPercentage = computed(() => {
  if (duration.value === 0) return 0
  return (currentTime.value / duration.value) * 100
})

const canStart = computed(() => {
  return status.value === 'STOPPED' && videoSource.value
})

const canStop = computed(() => {
  return ['RUNNING', 'PAUSED'].includes(status.value)
})

// 方法
const getStatusColor = (status) => {
  const colors = {
    'STARTING': 'bg-blue-100 text-blue-800',
    'RUNNING': 'bg-green-100 text-green-800',
    'PAUSED': 'bg-yellow-100 text-yellow-800',
    'STOPPED': 'bg-gray-100 text-gray-800',
    'ERROR': 'bg-red-100 text-red-800'
  }
  return colors[status] || 'bg-gray-100 text-gray-800'
}

const getStatusText = (status) => {
  const texts = {
    'STARTING': '启动中',
    'RUNNING': '运行中',
    'PAUSED': '暂停',
    'STOPPED': '已停止',
    'ERROR': '错误'
  }
  return texts[status] || status
}

const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60)
  const secs = Math.floor(seconds % 60)
  return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
}

const startVideoStream = async () => {
  loading.value = true
  try {
    // 获取会话信息
    const sessionResponse = await axios.get(`/api/slam/sessions/${props.sessionId}`)
    if (sessionResponse.data.code === 200) {
      const session = sessionResponse.data.data
      videoSource.value = session.videoSource
      
      // 启动会话
      const startResponse = await axios.post(`/api/slam/sessions/${props.sessionId}/start`)
      if (startResponse.data.code === 200) {
        status.value = 'RUNNING'
        
        // 设置视频源
        videoSrc.value = session.videoSource
        hasVideo.value = true
        
        // 启动视频
        if (mainVideo.value) {
          mainVideo.value.play()
          isPlaying.value = true
        }
      }
    }
  } catch (error) {
    console.error('启动视频流失败:', error)
    status.value = 'ERROR'
  } finally {
    loading.value = false
  }
}

const stopVideoStream = async () => {
  try {
    const response = await axios.post(`/api/slam/sessions/${props.sessionId}/stop`)
    if (response.data.code === 200) {
      status.value = 'STOPPED'
      isPlaying.value = false
      
      if (mainVideo.value) {
        mainVideo.value.pause()
        mainVideo.value.currentTime = 0
      }
    }
  } catch (error) {
    console.error('停止视频流失败:', error)
  }
}

const refreshVideoStream = async () => {
  await loadSessionStatus()
  await loadSlamInfo()
}

const loadSessionStatus = async () => {
  try {
    const response = await axios.get(`/api/slam/sessions/${props.sessionId}/status`)
    if (response.data.code === 200) {
      const data = response.data.data
      status.value = data.status
      
      if (data.videoSource) {
        videoSource.value = data.videoSource
        videoSrc.value = data.videoSource
        hasVideo.value = true
      }
    }
  } catch (error) {
    console.error('加载会话状态失败:', error)
  }
}

const loadSlamInfo = async () => {
  try {
    const response = await axios.get(`/api/slam/sessions/${props.sessionId}/trajectory`)
    if (response.data.code === 200) {
      const trajectory = response.data.data
      if (trajectory && trajectory.length > 0) {
        slamInfo.value = {
          keyframes: trajectory.filter(t => t.type === 'keyframe').length,
          mappoints: trajectory.filter(t => t.type === 'mappoint').length,
          trajectoryLength: calculateTrajectoryLength(trajectory)
        }
      }
    }
  } catch (error) {
    console.error('加载SLAM信息失败:', error)
  }
}

const calculateTrajectoryLength = (trajectory) => {
  let length = 0
  for (let i = 1; i < trajectory.length; i++) {
    const dx = (trajectory[i].x || 0) - (trajectory[i-1].x || 0)
    const dy = (trajectory[i].y || 0) - (trajectory[i-1].y || 0)
    const dz = (trajectory[i].z || 0) - (trajectory[i-1].z || 0)
    length += Math.sqrt(dx*dx + dy*dy + dz*dz)
  }
  return length
}

const togglePlayPause = () => {
  if (!mainVideo.value) return
  
  if (isPlaying.value) {
    mainVideo.value.pause()
    isPlaying.value = false
  } else {
    mainVideo.value.play()
    isPlaying.value = true
  }
}

const toggleMute = () => {
  if (!mainVideo.value) return
  
  mainVideo.value.muted = !mainVideo.value.muted
  isMuted.value = mainVideo.value.muted
}

const toggleFullscreen = () => {
  if (!fullscreen.value) {
    enterFullscreen()
  } else {
    exitFullscreen()
  }
}

const enterFullscreen = () => {
  fullscreen.value = true
  document.body.style.overflow = 'hidden'
}

const exitFullscreen = () => {
  fullscreen.value = false
  document.body.style.overflow = 'auto'
}

const onVideoLoaded = () => {
  if (mainVideo.value) {
    duration.value = mainVideo.value.duration
    videoResolution.value = `${mainVideo.value.videoWidth}x${mainVideo.value.videoHeight}`
    frameRate.value = Math.round(mainVideo.value.getVideoPlaybackQuality?.()?.totalVideoFrames / mainVideo.value.duration) || 30
  }
}

const onVideoError = (error) => {
  console.error('视频加载错误:', error)
  hasVideo.value = false
  status.value = 'ERROR'
}

// 监听sessionId变化
watch(() => props.sessionId, (newId) => {
  if (newId) {
    loadSessionStatus()
    loadSlamInfo()
  }
}, { immediate: true })

// 生命周期
onMounted(() => {
  // 定期更新SLAM信息
  const interval = setInterval(() => {
    if (status.value === 'RUNNING') {
      loadSlamInfo()
    }
  }, 2000)
  
  onUnmounted(() => {
    clearInterval(interval)
  })
})

// 键盘事件
const handleKeydown = (event) => {
  if (fullscreen.value) {
    switch (event.key) {
      case 'Escape':
        exitFullscreen()
        break
      case ' ':
        event.preventDefault()
        togglePlayPause()
        break
      case 'm':
      case 'M':
        toggleMute()
        break
    }
  }
}

onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
})
</script>

<style scoped>
.slam-realtime-view {
  width: 100%;
}

video {
  display: block;
}

/* 全屏样式 */
.fixed.inset-0 {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
}
</style>
